package com.wang.util;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.sql.*;
import java.util.Iterator;
import java.util.Map;

/**\
 *  将JDBC规范下相关对象创建与销毁功能封装
 *  一.JDBC开发步骤
 *      1.注册driver
 *      2.创建一个连接通道交给connection接口实例对象管理
 *      3.创建一个交通工具交给prepaerdStatement接口的实例对象(这玩意预编译,防止sql注入)
 *      4.由交通工具在java工程与数据库之间传输,推送sql命令并待会结果
 *      5.close
 */
public class JdbcUtil{

    private Connection con = null;//类文件的属性可以在所有方法中使用
    private PreparedStatement ps = null;

    /**
     * 不要轻易更改原方法的实现!!!我们想改则应该重载!
     * 我们要通过 createCon/createStatement方法重载,完成链接池的搭建
     */
    public Connection createCon(HttpServletRequest request){
        //1.通过请求对线给,得到全局作用域对象
        ServletContext application = request.getServletContext();
        //2.从全局作用域对象中得到listener中创建的map
        Map map = (Map) application.getAttribute("key1");
        //3.从map得到一个处于空闲状态的connection
        Iterator it =  map.keySet().iterator();//迭代器排序
        while(it.hasNext()){
            con = (Connection) it.next();
            //判断这个con的里面状态是不是true
            boolean flag = (Boolean) map.get(con);
            if (flag==true){
                map.put(con,false);//如果空闲,那么改变flag为忙碌
                break;
            }
        }
        return con;
    }
    public PreparedStatement createStatement(String sql,HttpServletRequest request){
        try {
            ps = createCon(request).prepareStatement(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ps;
    }


    //静态语句块,只加载一次static{},完成一次注册
    static{
        //1.注册driver
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("Driver接口实现类被注册");
    }
    //封装Connection对象创建细节
    public Connection createCon(){
        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","333");
        } catch (SQLException e) {
            System.out.println("Connection对象创建失败");
            e.printStackTrace();
        }
        return con;
    }

    //封装prepareStatement工具
    public PreparedStatement createStatement(String sql){
        con = createCon();
        try {
            ps = con.prepareStatement(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ps;
    }
//    //封装执行无rs的增删改执行语句
//    public int excute(String sql){
//        con = createCon();
//        PreparedStatement ps = createStatement(sql);
//        try {
//            ps.executeUpdate(sql);
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//    }
    /**
     * 如果想优化速度,不能销毁掉
     */
    public void close(HttpServletRequest request){
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        ServletContext application = request.getServletContext();
        Map map = (Map) application.getAttribute("key1");
        map.put(con,true);//将这个要关闭的con的value重新改为true空闲
    }
    //封装close:ps & con
    public void close(){
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        }
    //上面的方法重载 封装close:ps & con & resultset
    public void close(ResultSet rs){
        if (rs != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close();
        }
}




